package com.sunnay.util;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class BigDecimalUtil {

    public BigDecimalUtil() {
    }

    public static Integer multiply(String v1, String v2) {
        BigDecimal n1 = new BigDecimal(v1);
        BigDecimal n2 = new BigDecimal(v2);
        return n1.multiply(n2).intValue();
    }

    public static Double multiply(Long v1, Double v2) {
        BigDecimal n1 = new BigDecimal(v1);
        BigDecimal n2 = new BigDecimal(v2);
        return n1.multiply(n2).doubleValue();
    }

    public static Long multiply2Long(String v1, String v2) {
        BigDecimal n1 = new BigDecimal(v1);
        BigDecimal n2 = new BigDecimal(v2);
        return n1.multiply(n2).longValue();
    }

    public static Long multiply2Long(Integer v1, Integer v2) {
        BigDecimal n1 = new BigDecimal(v1.toString());
        BigDecimal n2 = new BigDecimal(v2.toString());
        return n1.multiply(n2).longValue();
    }

    public static Long multiply2Long(Long v1, Long v2) {
        BigDecimal n1 = new BigDecimal(v1.toString());
        BigDecimal n2 = new BigDecimal(v2.toString());
        return n1.multiply(n2).longValue();
    }

    public static Long multiply2Long(Long v1, Integer v2) {
        BigDecimal n1 = new BigDecimal(v1.toString());
        BigDecimal n2 = new BigDecimal(v2.toString());
        return n1.multiply(n2).longValue();
    }

    public static Long multiplyHundred(Integer v1) {
        return multiply2Long(v1, 100);
    }

    public static Double multiplyHundred(Double v1) {
        BigDecimal n1 = new BigDecimal(v1.toString());
        BigDecimal n2 = new BigDecimal("100");
        return n1.multiply(n2).doubleValue();
    }

    public static double multiply(String v1, String v2, Integer scale) {
        if (null == scale) {
            return (double)multiply(v1, v2);
        } else {
            BigDecimal n1 = new BigDecimal(v1);
            BigDecimal n2 = new BigDecimal(v2);
            return n1.multiply(n2).setScale(scale, 4).doubleValue();
        }
    }

    public static double div(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1);
            BigDecimal n2 = new BigDecimal(v2);
            return n1.divide(n2, scale, 4).doubleValue();
        }
    }

    public static Double div(Long v1, Long v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1.toString());
            BigDecimal n2 = new BigDecimal(v2.toString());
            return n1.divide(n2, scale, 4).doubleValue();
        }
    }

    public static Double div(Long v1, Integer v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1.toString());
            BigDecimal n2 = new BigDecimal(v2.toString());
            return n1.divide(n2, scale, 4).doubleValue();
        }
    }

    public static Double div(Integer v1, Integer v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1.toString());
            BigDecimal n2 = new BigDecimal(v2.toString());
            return n1.divide(n2, scale, 4).doubleValue();
        }
    }

    public static double divHundred(String v1) {
        return div((String)v1, (String)"100", 2);
    }

    public static Double divHundred(Long v1) {
        return div((String)v1.toString(), (String)"100", 2);
    }

    public static Double divHundred(Integer v1) {
        return div((String)v1.toString(), (String)"100", 2);
    }

    public static Double divHundred(String v1, int scale) {
        return div(v1, "100", scale);
    }

    public static Double divHundred(Long v1, int scale) {
        return div(v1.toString(), "100", scale);
    }

    public static Double divHundred(Integer v1, int scale) {
        return div(v1.toString(), "100", scale);
    }

    public static Double divHundred(Double v1, int scale) {
        return div(v1.toString(), "100", scale);
    }

    public static double add(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1);
            BigDecimal n2 = new BigDecimal(v2);
            return n1.add(n2).setScale(scale, RoundingMode.HALF_UP).doubleValue();
        }
    }

    public static long add(String v1, String v2) {
        BigDecimal n1 = new BigDecimal(v1);
        BigDecimal n2 = new BigDecimal(v2);
        return n1.add(n2).longValue();
    }

    public static double subtract(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1);
            BigDecimal n2 = new BigDecimal(v2);
            return n1.subtract(n2).setScale(scale, RoundingMode.HALF_UP).doubleValue();
        }
    }

    public static Double subtract(Long v1, Long v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1.toString());
            BigDecimal n2 = new BigDecimal(v2.toString());
            return n1.subtract(n2).setScale(scale, RoundingMode.HALF_UP).doubleValue();
        }
    }

    public static Double subtract(Integer v1, Integer v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1.toString());
            BigDecimal n2 = new BigDecimal(v2.toString());
            return n1.subtract(n2).setScale(scale, RoundingMode.HALF_UP).doubleValue();
        }
    }

    public static Double subtract(Long v1, Integer v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            BigDecimal n1 = new BigDecimal(v1.toString());
            BigDecimal n2 = new BigDecimal(v2.toString());
            return n1.subtract(n2).setScale(scale, RoundingMode.HALF_UP).doubleValue();
        }
    }

    public static double valueOf(Double d1, int scale) {
        return valueOf(String.valueOf(d1), scale);
    }

    public static double valueOf(String v1, int scale) {
        return valueOf(v1, scale, RoundingMode.HALF_UP);
    }

    public static double valueOf(String v1, int scale, RoundingMode mode) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        } else {
            return (new BigDecimal(v1)).setScale(scale, mode).doubleValue();
        }
    }

    public static int remainder(Double v1, Double v2) {
        BigDecimal b1 = new BigDecimal(v1.toString());
        BigDecimal b2 = new BigDecimal(v2.toString());
        return b1.remainder(b2).intValue();
    }
}
